#!/usr/bin/env node
import commander from "commander";
import fs from "fs";
import spawn from "cross-spawn";
import packageJson from "../package.json";
import { createProject } from "./create-seeyon-app";
import { resolveApp, resolveSeeyonSyf } from "../scripts/resolve";

const program = new commander.Command();

program.version(packageJson.version, "-v, --version");

program.command("start").description("启动开发环境").action(runStart);

program.command("build").description("构建项目").action(runBuild);

program.command("deploy").description("上传资源").action(runDeploy);

program
	.command("test")
	.description("单元测试")
	.option("-d, --describe <describe>", "单独运行，单元测试的describe名称")
	.option("-f, --file <file>", "单独运行，单元测试的文件名称")
	.action((source) => {
		runTest(source);
	});

program.command("analyse").description("分析项目依赖").action(runAnalyse);

program
	.command("copy")
	.description("拷贝jenkins, dockerfile和nginx.template文件")
	.action(runCopy);

program.command("lint").description("代码检查").action(runLint);

program.command("format").description("代码格式化").action(runFormat);

program
	.command("new <projectName>")
	.description("创建新项目")
	.option("-t, --template <template>", "创建应用模板类型")
	.option("-n, --noverify", "不验证版本")
	.action(function (projectName, options) {
		createProject(projectName, options.template, options.noverify);
	});

program.command("filter").description("扫描体积超标的文件").action(runFilter);

program.parse(process.argv);

function runStart() {
	const portfinder = require("portfinder");
	portfinder.basePort = 3000;
	portfinder
		.getPortPromise()
		.then((port) => {
			process.env.PORT = port;

			const projectPath = `${process.cwd()}/node_modules`;

			spawn.sync(
				"cross-env",
				[
					"NODE_ENV=development",
					`${projectPath}/.bin/webpack`,
					"serve",
					"--config",
					require.resolve("../scripts/start.js"),
					"--progress",
				],
				{
					stdio: "inherit",
				},
			);
		})
		.catch((err) => {
			console.log("ERROR ", err);
		});
}

function runTest(source) {
	const projectPath = `${process.cwd()}/node_modules`;
	const syfRootPath = `${projectPath}/@seeyon/syf`;
	let args = [
		"NODE_ENV=development",
		"NODE_ENV_TEST=true",
		`${projectPath}/jest/bin/jest.js`,
		`--config=${syfRootPath}/scripts/jest.js`,
		"--coverage",
	];
	source.file && args.push(source.file);
	source.describe && args.push(`-t=${source.describe}`);
	spawn.sync("cross-env", args, {
		stdio: "inherit",
	});
}

function runBuild() {
	const projectPath = `${process.cwd()}/node_modules`;
	const buildType =
		["zip", "default"].indexOf(process.argv[3]) >= 0
			? process.argv[3]
			: "default";
	const args = [
		"NODE_ENV=production",
		`BUILD_TYPE=${buildType}`,
		`${projectPath}/webpack/bin/webpack.js`,
		"--config",
		require.resolve("../scripts/build.js"),
		"--progress",
	];

	spawn.sync("cross-env", args, {
		stdio: "inherit",
	});
}

function runAnalyse() {
	const projectPath = `${process.cwd()}/node_modules`;
	const args = [
		"ANALYSE=true",
		"NODE_ENV=production",
		`${projectPath}/webpack/bin/webpack.js`,
		"--config",
		require.resolve("../scripts/build.js"),
	];
	spawn.sync("cross-env", args, {
		stdio: "inherit",
	});
}

function runLint() {
	const projectPath = `${process.cwd()}/node_modules`;

	spawn.sync(
		`${projectPath}/.bin/eslint`,
		[
			"--ext",
			".js",
			"--ext",
			".jsx",
			"--ext",
			".ts",
			"--ext",
			".tsx",
			resolveApp("src"),
		],
		{
			stdio: "inherit",
		},
	);
}

function runFormat() {
	const projectPath = `${process.cwd()}/node_modules`;

	spawn.sync(
		`${projectPath}/.bin/prettier`,
		["--write", "src/**/*.{js,jsx,tsx,ts,less,md,json}"],
		{
			stdio: "inherit",
		},
	);
}

function runCopy() {
	try {
		fs.copyFileSync(
			`${resolveSeeyonSyf("")}/jenkins.js`,
			`${resolveApp("")}/jenkins.js`,
		);
		fs.copyFileSync(
			`${resolveSeeyonSyf("")}/nginx.template`,
			`${resolveApp("")}/nginx.template`,
		);
	} catch (e) {
		console.error(e);
		console.error("\x1b[41m%s\x1b[0m", e.message);
		process.exit(1);
	}
}

function runDeploy() {
	try {
		const args = [
			"NODE_ENV=devlopment",
			"node",
			`${resolveSeeyonSyf("")}/scripts/deploy.js`,
		];
		spawn.sync("cross-env", args, {
			stdio: "inherit",
		});
	} catch (e) {
		console.error(e);
		console.error("\x1b[41m%s\x1b[0m", e.message);
		process.exit(1);
	}
}

function runFilter() {
	try {
		const args = [
			"node",
			`${resolveSeeyonSyf("")}/scripts/filter-fat-files.js`,
		];
		spawn.sync("cross-env", args, {
			stdio: "inherit",
		});
	} catch (e) {
		console.error(e);
		console.error("\x1b[41m%s\x1b[0m", e.message);
		process.exit(1);
	}
}
